<?php

class EncryptionException extends Exception
{
}

class Encryption
{

	static function changePassphrase ($private, $old, $new=null) {
		$res = openssl_pkey_get_private ($private, $old);
		if ($res === false) {
			throw new EncryptionException ("Loading private key failed: ".openssl_error_string ());
			return false;
		}
		if (openssl_pkey_export ($res, $result, $new) === false) {
			throw new EncryptionException ("Passphrase change failed: ".openssl_error_string ());
			return false;
		}
		return $result;
	}

	static function newPair (&$private, &$public, $passphrase=null) {
		$res = openssl_pkey_new ();
		if ($res === false) {
			throw new EncryptionException ("Key generation failed: ".openssl_error_string ());
			return false;
		}
		// Sets private by reference
		if (openssl_pkey_export ($res, $private, $passphrase) === false) {
			throw new EncryptionException ("Private key export failed: ".openssl_error_string ());
			return false;
		}
		// Array returns, contains "key" element.
		$public = openssl_pkey_get_details($res);
		if ($public === false) {
			throw new EncryptionException (openssl_error_string ());
			return false;
		}
		$public = $public["key"];
		return true;
	}

	static function encryptPublic ($public, $cleartext) {
		if (openssl_public_encrypt ($cleartext, $result, $public) === false) {
			throw new EncryptionException ("Encryption failed: ".openssl_error_string ());
			return false;
		}
		return $result;
	}
	
	static function decryptPrivate ($private, $encrypted, $passphrase=null) {
		$res = openssl_pkey_get_private ($private, $passphrase);
		if ($res === false) {
			throw new EncryptionException ("Loading private key failed: ".openssl_error_string ());
		}
		if (openssl_private_decrypt ($encrypted, $result, $res) === false) {
			throw new EncryptionException ("Decryption failed: ".openssl_error_string ());
			return false;
		}
		return $result;
	}
	
	function encryptAES($str, $key) {
		return rtrim (
			base64_encode (
				mcrypt_encrypt (
					MCRYPT_RIJNDAEL_256,
					$key, $str, 
					MCRYPT_MODE_ECB, 
					mcrypt_create_iv (
						mcrypt_get_iv_size (
							MCRYPT_RIJNDAEL_256, 
							MCRYPT_MODE_ECB
						), 
						MCRYPT_RAND)
					)
				), "\0"
			);
	}

	function decryptAES($str, $key) {
		return rtrim (
			mcrypt_decrypt (
				MCRYPT_RIJNDAEL_256, 
				$key, 
				base64_decode ($str), 
				MCRYPT_MODE_ECB,
				mcrypt_create_iv (
					mcrypt_get_iv_size (
						MCRYPT_RIJNDAEL_256,
						MCRYPT_MODE_ECB
					), 
					MCRYPT_RAND
				)
			), "\0"
		);
	}
	
}